package com.waypolice.manager.controller;

import com.waypolice.common.constant.CmsResult;
import com.waypolice.common.constant.VolItemConstant;
import com.waypolice.common.utils.FastDfsClient;
import com.waypolice.common.utils.MathUtils;
import com.waypolice.manager.component.AddressUploadThread;
import com.waypolice.manager.service.CmsSinItemService;
import com.waypolice.manager.service.UserService;
import com.waypolice.manager.service.VolAndItemService;
import com.waypolice.pojo.CmsJudItem;
import com.waypolice.pojo.CmsSinItem;
import com.waypolice.pojo.UpmsUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 描述:
 *
 * @author zyp
 * @description 文件上传action
 * @create 2019-03-13 14:28
 */
@Controller
@Api(value = "文件上传控制器", description = "文件上传")
@RequestMapping(value="/pcwindow")
public class FileUploadAction {

    private static final Logger logger = LoggerFactory.getLogger(FileUploadAction.class);

    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(5);

    // 放弃拒绝的任务并抛出异常
    private static RejectedExecutionHandler discardPolicyHandler = new ThreadPoolExecutor.DiscardPolicy();

    private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS, workQueue, discardPolicyHandler);

    @Value("${IMAGE_SERVER_URL}")
    private String IMAGE_SERVER_URL;

    @Autowired
    private VolAndItemService volAndItemService;

    @Autowired
    private CmsSinItemService cmsSinItemService;

    @Autowired
    protected UserService userService;

    /**
     * @author:zyp
     * @description 文件上传
     * @date: 2019/3/13 14:34
     * @return 
     */
    @ApiOperation(value = "文件上传")
    @RequestMapping(value = "/uploadFile")
    @ResponseBody
    public Object uploadFile(@RequestParam(value = "file", required = false) MultipartFile file,
                                       HttpServletRequest request, HttpServletResponse response){
        String fileId = request.getParameter("fileId");
        String type = request.getParameter("fileType");
        //判断当前上传的文件名称是否有与卷中内容相匹配名称，默认没有
        boolean isMate = false;
        try {
            switch (type){
                //如果是卷
                case VolItemConstant.FILE_TYPE_VOL:
                    String[] ids = fileId.split(",");
                    List<CmsJudItem> cmsJudItems = volAndItemService.selectAllByVolIds(Arrays.asList(ids));
                    for(CmsJudItem cmsJudItem : cmsJudItems){
                        String cmsJudItemName = cmsJudItem.getItemStr1();
                        //判断卷中的文件与上传的文件件名是否相同
                        isMate = uploadFastDfsAndUpItem(cmsJudItem,file,cmsJudItemName,isMate);
                        if (isMate){
                            break;
                        }
                    }
                    break;
                //如果是件
                case VolItemConstant.FILE_TYPE_ITEM:
                    CmsJudItem cmsJudItem = volAndItemService.selectByItemId(MathUtils.string2long(fileId));
                    String cmsJudItemName = cmsJudItem.getItemStr1();
                    //判断卷中的文件与上传的文件件名是否相同
                    isMate = uploadFastDfsAndUpItem(cmsJudItem,file,cmsJudItemName,isMate);
                    break;
                //如果是单件批量
                case VolItemConstant.FILE_TYPE_SIN_ITEM:
                    String[] volIds = fileId.split(",");
                    List<CmsSinItem> cmsSinItems = cmsSinItemService.selectSimItemsByIds(Arrays.asList(volIds));
                    for(CmsSinItem cmsSinItem : cmsSinItems){
                        String cmsSinItemName = cmsSinItem.getItemStr1();
                        //判断卷中的文件与上传的文件件名是否相同
                        isMate = uploadFastDfsAndUpSinItem(cmsSinItem,file,cmsSinItemName,isMate);
                        if (isMate){
                            break;
                        }
                    }
                    break;
                    default:
            }
            //如果没有匹配到内容，则抛出异常
            if(!isMate){
                return new CmsResult(0,"fail",null);
            }
        } catch (Exception e){
            return new CmsResult(0,"fail",null);
        }
        return new CmsResult(1,"success",null);
    }
    
    /**
     * @author:zyp
     * @description 单一文件上传
     * @date: 2019/4/4 10:25
     * @return 
     */
    @ApiOperation(value = "单一文件上传")
    @RequestMapping(value = "/uploadSingleFile")
    @ResponseBody
    public Object uploadSingleFile(@RequestParam(value = "file", required = false) MultipartFile file,
                                       HttpServletRequest request, HttpServletResponse response){
        String fileId = request.getParameter("fileId");
        String type = request.getParameter("fileType");
        //判断当前上传的文件名称是否有与卷中内容相匹配名称，默认没有
        boolean isMate = false;
        try {
            //不可能是卷
            switch (type){
                //如果是件
                case VolItemConstant.FILE_TYPE_ITEM:
                    CmsJudItem cmsJudItem = volAndItemService.selectByItemId(MathUtils.string2long(fileId));
                    //判断卷中的文件与上传的文件件名是否相同
                    isMate = uploadFastDfsAndSingleUpItem(cmsJudItem,file);
                    break;
                //如果是单件批量
                case VolItemConstant.FILE_TYPE_SIN_ITEM:
                    CmsSinItem cmsSinItem = cmsSinItemService.selectSinItemById(MathUtils.string2long(fileId));
                    //判断卷中的文件与上传的文件件名是否相同
                    isMate = uploadFastDfsAndUpSingleSinItem(cmsSinItem,file);
                    if (isMate){
                        break;
                    }
                    break;
                    default:
            }
            //如果没有匹配到内容，则抛出异常
            if(!isMate){
                return new CmsResult(0,"fail",null);
            }
        } catch (Exception e){
            return new CmsResult(0,"fail",null);
        }
        return new CmsResult(1,"success",null);
    }


    /**
     * @author:zyp
     * @description 根据地址，或者是ftp或者是本地，进行挂接
     * @date: 2019/6/21 13:41
     * @return
     */
    @ApiOperation(value = "根据地址，或者是ftp或者是本地，进行挂接")
    @RequestMapping(value = "/uploadByAddress")
    @ResponseBody
    public Object uploadByAddress(HttpServletRequest request, HttpServletResponse response){
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        List<UpmsUser> user = userService.findByName(username);
        UpmsUser upmsUser= user.get(0);
        //查看当前用户下是否存在正在挂接的任务，如果当前的map中存在该账户并且该账户的value值为null，则证明该账户正在执行挂接任务
        if (AddressUploadThread.userUploadStatus.containsKey(upmsUser.getUsername())&&AddressUploadThread.userUploadStatus.get(upmsUser.getUsername())==null){
            return new CmsResult(0,"你现在正在执行挂接任务，请稍后再试！！！！",null);
        }
        AddressUploadThread.userUploadStatus.put(upmsUser.getUsername(),null);
        String FTPIp = request.getParameter("FTPIp");
        String FTPPort = request.getParameter("FTPPort");
        String FTPUser = request.getParameter("FTPUser");
        String FTPPassword = request.getParameter("FTPPassword");
        String FTPPath = request.getParameter("FTPPath");
        String localAddress = request.getParameter("localAddress");
        String fileId = request.getParameter("volIds");
        String type = request.getParameter("type");
        AddressUploadThread addressUploadThread = new AddressUploadThread();
        addressUploadThread.setFTPIp(FTPIp);
        addressUploadThread.setFTPPort(FTPPort);
        addressUploadThread.setFTPUser(FTPUser);
        addressUploadThread.setFTPPassword(FTPPassword);
        addressUploadThread.setFTPPath(FTPPath);
        addressUploadThread.setFileId(fileId);
        addressUploadThread.setType(type);
        addressUploadThread.setLocalAddress(localAddress);
        addressUploadThread.setUserName(upmsUser.getUsername());
        threadPool.execute(addressUploadThread);
        return new CmsResult(1,"挂接任务执行中...，请时刻关注首页消息提示！",null);
    }

    /**
     * @author:zyp
     * @description 上传到fastDfs中,并修改件表状态 公共方法
     * @date: 2019/3/14 17:58
     * @return 
     */
    public boolean uploadFastDfsAndUpItem(CmsJudItem cmsJudItem,MultipartFile file,String cmsJudItemName,boolean isMate) throws Exception {
        // 取扩展名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //去掉扩展名的文件名
        String fileNameNotExt = originalFilename.substring(0,originalFilename.lastIndexOf("."));
        String itemAdress = cmsJudItem.getItemStr2();
        if(StringUtils.isNotBlank(cmsJudItemName)&&cmsJudItemName.equals(fileNameNotExt)){
            //如果地址不为空的话就不需要重新上传----此处待定
//            if(StringUtils.isBlank(itemAdress)){
                FastDfsClient fastDFSClient = new FastDfsClient("classpath:client.conf");
                String fastDfSUrl = fastDFSClient.uploadFile(file.getBytes(),extName);
                if(StringUtils.isNotBlank(fastDfSUrl)){
                    String fastDfsUrl = cmsJudItem.getItemStr2();
                    if(StringUtils.isNotBlank(fastDfsUrl)){
                        fastDFSClient.deleteFile(fastDfsUrl.replace(IMAGE_SERVER_URL,""));
                    }
                    String imagesUrl = IMAGE_SERVER_URL + fastDfSUrl;
                    cmsJudItem.setItemStr2(imagesUrl);
                    cmsJudItem.setItemStr3("1");
                    volAndItemService.updateItemByPrimaryKeySelective(cmsJudItem);
                }

//            }
            isMate = true;
        }
        return isMate;
    }

    /**
     * @author:zyp
     * @description 上传到fastDfs中,并修改单件表状态 公共方法
     * @date: 2019/3/27 10:05
     * @return 
     */
    public boolean uploadFastDfsAndUpSinItem(CmsSinItem cmsSinItem,MultipartFile file,String cmsJudItemName,boolean isMate) throws Exception {
        // 取扩展名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //去掉扩展名的文件名
        String fileNameNotExt = originalFilename.substring(0,originalFilename.lastIndexOf("."));
        String itemAdress = cmsSinItem.getItemStr2();
        if(StringUtils.isNotBlank(cmsJudItemName)&&cmsJudItemName.equals(fileNameNotExt)){
            //如果地址不为空的话就不需要重新上传----此处待定
//        if(StringUtils.isBlank(itemAdress)){
            FastDfsClient fastDFSClient = new FastDfsClient("classpath:client.conf");
            String fastDfSUrl = fastDFSClient.uploadFile(file.getBytes(),extName);
            if (StringUtils.isNotBlank(fastDfSUrl)){
                String fastDfsUrl = cmsSinItem.getItemStr2();
                if(StringUtils.isNotBlank(fastDfsUrl)){
                    fastDFSClient.deleteFile(fastDfsUrl.replace(IMAGE_SERVER_URL,""));
                }
                String imagesUrl = IMAGE_SERVER_URL + fastDfSUrl;
                cmsSinItem.setItemStr2(imagesUrl);
                cmsSinItem.setItemStr3("1");
                cmsSinItemService.updateSinItemByPrimaryKeySelective(cmsSinItem);
            }
//        }
            isMate = true;
        }
        return isMate;
    }

    /**
     * @author:zyp
     * @description 上传到fastDfs中,针对于单一文件上传
     * @date: 2019/3/14 17:58
     * @return
     */
    public boolean uploadFastDfsAndSingleUpItem(CmsJudItem cmsJudItem,MultipartFile file) throws Exception {
        // 取扩展名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //如果地址不为空的话就不需要重新上传----此处待定
        String itemAdress = cmsJudItem.getItemStr2();
//        if(StringUtils.isBlank(itemAdress)){
            FastDfsClient fastDFSClient = new FastDfsClient("classpath:client.conf");
            String fastDfSUrl = fastDFSClient.uploadFile(file.getBytes(),extName);
            String imagesUrl = IMAGE_SERVER_URL + fastDfSUrl;
            cmsJudItem.setItemStr2(imagesUrl);
            cmsJudItem.setItemStr3("1");
            volAndItemService.updateItemByPrimaryKeySelective(cmsJudItem);
//        }
        return true;
    }

    /**
     * @author:zyp
     * @description 上传到fastDfs中,针对于单一单件文件上传
     * @date: 2019/3/27 10:05
     * @return
     */
    public boolean uploadFastDfsAndUpSingleSinItem(CmsSinItem cmsSinItem,MultipartFile file) throws Exception {
        // 取扩展名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        String itemAdress = cmsSinItem.getItemStr2();
        //如果地址不为空的话就不需要重新上传----此处待定
//        if(StringUtils.isBlank(itemAdress)){
            FastDfsClient fastDFSClient = new FastDfsClient("classpath:client.conf");
            String fastDfSUrl = fastDFSClient.uploadFile(file.getBytes(),extName);
            String imagesUrl = IMAGE_SERVER_URL + fastDfSUrl;
            cmsSinItem.setItemStr2(imagesUrl);
            cmsSinItem.setItemStr3("1");
            cmsSinItemService.updateSinItemByPrimaryKeySelective(cmsSinItem);
//        }
        return true;
    }

}